package org.juggers.client.controller;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import org.juggers.client.JuggersMessages;
import org.juggers.client.ui.ConnectionPanel;
import org.juggers.client.ui.ForgottenPasswordDialogBox;
import org.juggers.client.ui.RegistrationDialogBox;
import org.juggers.client.ui.UserPanel;
import org.juggers.domain.AlreadyConfirmedException;
import org.juggers.domain.AlreadyRegisteredException;
import org.juggers.domain.AuthenticationException;
import org.juggers.domain.InvalidCaptchaException;
import org.juggers.domain.InvalidEmailException;
import org.juggers.domain.InvalidTokenException;
import org.juggers.domain.Jugger;
import org.juggers.domain.ModelState;
import org.juggers.domain.PendingException;
import org.juggers.remote.RegistrationRemoteServiceAsync;
import org.juggers.remote.UserRemoteServiceAsync;

import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.inject.Inject;
import com.google.inject.Singleton;

/**
 * Controller
 * 
 * @author <a href="mailto:michel@breizhjug.org">Michel DAVID</a>
 */
@Singleton
public class JuggerController
{
    @Inject
    private ModelState model;

    @Inject
    private JuggersMessages messages;

    @Inject
    private RegistrationRemoteServiceAsync registrationService;

    @Inject
    private UserRemoteServiceAsync userService;

    @Inject
    private RegistrationDialogBox registrationDialogBox;

    @Inject
    private ForgottenPasswordDialogBox forgottenPasswordDialogBox;

    @Inject
    private ConnectionPanel connectionPanel;

    @Inject
    private UserPanel userPanel;

    /**
     * Show registration dialog box
     */
    public void showRegistration()
    {
        registrationDialogBox.show();
        registrationDialogBox.center();
    }

    /**
     * Cancel registration, hide registration dialog box
     */
    public void cancelRegistration()
    {
        registrationDialogBox.hide();
    }

    /**
     * Register a jugger
     * 
     * @param jugger Jugger
     */
    public void register( Jugger jugger, String captchaChallenge, String captchaResponse )
    {
        registrationService.register( jugger, captchaChallenge, captchaResponse, new AsyncCallback<Void>()
        {

            @Override
            public void onSuccess( Void arg0 )
            {
                registrationDialogBox.hide();
                Window.alert( messages.registered() );
            }

            @Override
            public void onFailure( Throwable t )
            {
                if ( t instanceof AlreadyRegisteredException )
                {
                    Window.alert( messages.alreadyRegistered() );
                }
                else if ( t instanceof InvalidCaptchaException )
                {
                    Window.alert( messages.invalidCaptcha() );
                }
                else
                {
                    Window.alert( messages.error( t.getMessage() ) );
                }
                registrationDialogBox.reloadCaptcha();
            }
        } );
    }

    /**
     * Confirm a jugger registration
     * 
     * @param eMail Jugger email
     * @param token Confirmation token
     */
    public void confirm( String eMail, String token )
    {
        registrationService.confirm( eMail, token, new AsyncCallback<Jugger>()
        {

            @Override
            public void onSuccess( Jugger arg0 )
            {
                Window.alert( messages.confirmed() );
            }

            @Override
            public void onFailure( Throwable t )
            {
                if ( t instanceof InvalidTokenException )
                {
                    Window.alert( messages.invalidToken() );
                }
                else if ( t instanceof AlreadyConfirmedException )
                {
                    Window.alert( messages.alreadyConfirmed() );
                }
                else
                {
                    Window.alert( messages.error( t.getMessage() ) );
                }
            }
        } );
    }

    /**
     * Jugger authentication
     * 
     * @param login Login
     * @param password Password
     */
    public void login( String login, String password )
    {
        userService.login( login, password, new AsyncCallback<Jugger>()
        {

            @Override
            public void onSuccess( Jugger result )
            {
                RootPanel cnx = RootPanel.get( "cnx" );
                cnx.clear();
                cnx.add( userPanel );

                model.setConnectedJugger( result );
            }

            @Override
            public void onFailure( Throwable t )
            {
                if ( t instanceof PendingException )
                {
                    Window.alert( messages.pending() );
                }
                else if ( t instanceof AuthenticationException )
                {
                    Window.alert( messages.authenticationError() );
                }
                else
                {
                    Window.alert( messages.error( t.getMessage() ) );
                }
            }
        } );
    }

    /**
     * Jugger logout
     */
    public void logout()
    {
        model.setConnectedJugger( null );
        connectionPanel.clearPassword();

        RootPanel cnx = RootPanel.get( "cnx" );
        cnx.clear();
        cnx.add( connectionPanel );
    }

    /**
     * Show forgotten password dialogBox
     */
    public void showForgottenPassword()
    {
        forgottenPasswordDialogBox.show();
        forgottenPasswordDialogBox.center();
    }

    /**
     * Close forgotten password dialogBox
     */
    public void cancelForgottenPassword()
    {
        forgottenPasswordDialogBox.hide();
    }

    /**
     * Send forgotten password
     * 
     * @param email Email
     * @param captchaChallenge Captcha challenge
     * @param captchaResponse Captcha response
     */
    public void forgottenPassword( String email, String captchaChallenge, String captchaResponse )
    {
        userService.sendPassword( email, captchaChallenge, captchaResponse, new AsyncCallback<Void>()
        {

            @Override
            public void onSuccess( Void result )
            {
                forgottenPasswordDialogBox.hide();
                Window.alert( messages.passwordSended() );
            }

            @Override
            public void onFailure( Throwable t )
            {
                if ( t instanceof InvalidEmailException )
                {
                    Window.alert( messages.invalidEmail() );
                }
                else if ( t instanceof InvalidCaptchaException )
                {
                    Window.alert( messages.invalidCaptcha() );
                }
                else
                {
                    Window.alert( messages.error( t.getMessage() ) );
                }
                forgottenPasswordDialogBox.reloadCaptcha();
            }
        } );
    }
}
